package com.yami.shop.admin.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.admin.config.Constants;
import com.yami.shop.admin.config.PayUtil;
import com.yami.shop.bean.model.CashOut;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.bean.model.PromoTionOrder;
import com.yami.shop.bean.model.User;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.security.util.SecurityUtils;
import com.yami.shop.service.CashOutService;
import com.yami.shop.service.ShopDetailService;
import com.yami.shop.service.UserService;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.net.ssl.SSLContext;
import javax.validation.Valid;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.text.ParseException;
import java.util.*;

/**
 * 提现审核
 */
@RestController
@RequestMapping("/cashOut")
public class CashOutController {
    private  int socketTimeout = 10000;// 连接超时时间，默认10秒
    private  int connectTimeout = 30000;// 传输超时时间，默认30秒
    private  static RequestConfig requestConfig;// 请求器的配置
    private  static CloseableHttpClient httpClient;// HTTP请求器
    @Autowired
    private CashOutService cashOutService;
    @Autowired
    private ShopDetailService shopDetailService;
    @Autowired
    private UserService userService;
    /**
     * 获取后台首页数据
     */
    @GetMapping("/pageByShop")
    public ResponseEntity<IPage<CashOut>> pageByshop(CashOut cashOut, PageParam<CashOut> page){
        IPage<CashOut> cashOutIPage = cashOutService.page(page,new LambdaQueryWrapper<CashOut>()
                .eq(CashOut::getUserType, "1")
                .orderByDesc(CashOut::getCashId));
        return ResponseEntity.ok(cashOutIPage);
    }

    /**
     * 获取后台首页数据
     */
    @GetMapping("/pageByUser")
    public ResponseEntity<IPage<CashOut>> pageByuser(CashOut cashOut, PageParam<CashOut> page){
        IPage<CashOut> cashOutIPage = cashOutService.page(page,new LambdaQueryWrapper<CashOut>()
                .eq(CashOut::getUserType, "2")
                .orderByDesc(CashOut::getCashId));
        return ResponseEntity.ok(cashOutIPage);
    }




    /**
     * 保存
     */
    @PostMapping
    public ResponseEntity<Void> save(@Valid @RequestBody CashOut cashOut) throws ParseException {
        Long shopId = SecurityUtils.getSysUser().getShopId();
        Long userId = SecurityUtils.getSysUser().getUserId();
        cashOut.setShopId(shopId);
        cashOut.setState(0);
        cashOut.setCreateTime(new Date());
        cashOutService.save(cashOut);
        return ResponseEntity.ok().build();
    }

    /**
     * 提现审核修改状态
     */
    @PutMapping
    public ResponseEntity<Void> update(@Valid @RequestBody CashOut cashOut){
        cashOut.setApprovalTime(new Date());
        cashOutService.updateAndCash(cashOut);
        return ResponseEntity.ok().build();
    }

    /**
     * 删除
     */
    @DeleteMapping
    public ResponseEntity<Void> delete(@RequestBody Long[] ids){
        cashOutService.removeByIds(Arrays.asList(ids));
        return ResponseEntity.ok().build();
    }

    /**
     * 获取推广首页的数据
     */
    @PostMapping("/getpromotionIncome")
    public ResponseEntity<Map> getpromotionIncome(){
        Map map = new HashMap();
        String userId = SecurityUtils.getUser().getUserId();
        //获取累计推广金额
        String allIncome = cashOutService.getAllIncome(userId);
        //获取可提现金额
        User user = userService.getUserByUserId(userId);
        Double account = 0.00;
        if(null!=user){
            account =  user.getAccount();
        }
        map.put("allIncome",allIncome);
        map.put("account",account);
        return ResponseEntity.ok(map);
    }

    //商家申请提现
    @GetMapping("/cashoutByShop")
    private  ResponseEntity<String>  cashoutByShop(String cashOutMoney){
        String result = "success";
        Long shopId =  SecurityUtils.getSysUser().getShopId();
        //申请提现(当申请的时候,先扣除提现金额,当审核成功后,提现金额到账,当审核失败了,提现金额返回)
        cashOutService.cashOutByShop(shopId,cashOutMoney);
        return ResponseEntity.ok(result);
    }

    //提现审核
    @PostMapping("/checkingCashOut")
    private ResponseEntity<String> checkingCashOut(String cashId,String status){
        String result ="success";
        CashOut cashOut = cashOutService.getById(Long.valueOf(cashId));
        cashOut.setState(Integer.valueOf(status));
        cashOut.setApprovalTime(new Date());
        cashOutService.saveOrUpdate(cashOut);
        return  ResponseEntity.ok(result);
    }

    /**
     * 获得推广订单
     */
    @GetMapping("/getPromoTionOrder")
    public ResponseEntity<Map>  getPromoTionOrder(String userId){
        Map map = new HashMap();
        //获得所有结算的订单
        List<PromoTionOrder> yjsOrderList = cashOutService.getyjsOrder(userId);
        if(null!=yjsOrderList){
            for(PromoTionOrder promoTionOrder:yjsOrderList){
                //订单编号
                String orderNumber = promoTionOrder.getOrderNumber();
                //获取子订单
                List<OrderItem> orderItemList = cashOutService.getOrderItem(orderNumber);
                promoTionOrder.setOrderItemList(orderItemList);
            }
            map.put("yjsOrderList",yjsOrderList);
            map.put("yjsOrderListSize",yjsOrderList.size());
        }
        return  ResponseEntity.ok(map);
    }

    /**
     * 企业转账到个人
     * @throws Exception
     */
    public void transfer() throws Exception{
        String code = Constants.CODE_SUCCESS;//状态码
        String msg = Constants.REFUND_SUCCESS;//提示信息
        Map <String,String> data = new HashMap<String,String>();
        try {
            //退款到用户微信
            String nonce_str = getRandomStringByLength(32);
            data.put("mch_appid", Constants.appID);
            data.put("mchid", Constants.MCH_ID);
            data.put("nonce_str", nonce_str);
            data.put("partner_trade_no", "0000001");//商户订单号
            data.put("openid","oWG8S5R2RafYyu2_VOd71NTFosWY");
            data.put("check_name", "NO_CHECK"); //校验用户姓名选项 OPTION_CHECK
            data.put("amount","100");//转账金额
            data.put("desc", "商家提现"); //企业付款描述信息
            String preStr = PayUtil.createLinkString(data); // 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
            //MD5运算生成签名，这里是第一次签名，用于调用统一下单接口
            String mySign = PayUtil.sign(preStr, Constants.key, "utf-8").toUpperCase();
            data.put("sign", mySign);
            //拼接统一下单接口使用的xml数据，要将上一步生成的签名一起拼接进去
            String pjxml = PayUtil.GetMapToXML(data);
            System.out.println(pjxml);
            String xmlStr = postData(Constants.TRANSFER_PATH, PayUtil.GetMapToXML(data)); //支付结果通知的xml格式数据
            System.out.println(xmlStr);
            Map notifyMap = PayUtil.doXMLParse(xmlStr);
        }catch (Exception e) {
            code = Constants.CODE_ERROR;
            msg = Constants.MSG_01;
        }
    }

    private  String getRandomStringByLength(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    public  String postData(String url, String xmlObj) {
        // 加载证书
        try {
            initCert();
        } catch (Exception e) {
            e.printStackTrace();
        }
        String result = null;
        HttpPost httpPost = new HttpPost(url);
        // 得指明使用UTF-8编码，否则到API服务器XML的中文不能被成功识别
        StringEntity postEntity = new StringEntity(xmlObj, "UTF-8");
        httpPost.addHeader("Content-Type", "text/xml");
        httpPost.setEntity(postEntity);
        // 根据默认超时限制初始化requestConfig
        requestConfig = RequestConfig.custom()
                .setSocketTimeout(socketTimeout)
                .setConnectTimeout(connectTimeout)
                .build();
        // 设置请求器的配置
        httpPost.setConfig(requestConfig);
        try {
            HttpResponse response = null;
            try {
                response = httpClient.execute(httpPost);
            }  catch (IOException e) {
                e.printStackTrace();
            }
            HttpEntity entity = response.getEntity();
            try {
                result = EntityUtils.toString(entity, "UTF-8");
            }  catch (IOException e) {
                e.printStackTrace();
            }
        } finally {
            httpPost.abort();
        }
        return result;
    }

    private static void initCert() throws Exception {
        // 证书密码，默认为商户ID
        String key = Constants.MCH_ID;
        // 商户证书的路径
        //String path = Constants.CERT_PATH;
        //String filePath = RefundController.class.getClassLoader().getResource("apiclient_cert.p12").getFile();
        InputStream instream=CashOutController.class.getResourceAsStream("/apiclient_cert.p12");
        // 指定读取证书格式为PKCS12
        KeyStore keyStore = KeyStore.getInstance("PKCS12");

        // 读取本机存放的PKCS12证书文件
        //FileInputStream instream = new FileInputStream(new File(filePath));
        try {
            // 指定PKCS12的密码(商户ID)
            keyStore.load(instream, key.toCharArray());
        } finally {
            instream.close();
        }

        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build();

        // 指定TLS版本
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        // 设置httpclient的SSLSocketFactory
        httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
    }





}
